import requests as req
from re import search, findall
from os import system
from sys import exit

headers = {
    'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36',
    # 'Cookie': "_uuid=1DBA4F96-2E63-8488-DC25-B8623EFF40E773841infoc; buvid3=FE0D3174-E871-4A3E-877C-A4ED86E20523155831infoc; LIVE_BUVID=AUTO8515670521735348; sid=l765gx48; DedeUserID=33717177; DedeUserID__ckMd5=be4de02fd64f0e56; SESSDATA=cf65a5e0%2C1569644183%2Cc4de7381; bili_jct=1e8cdbb5755b4ecd0346761a121650f5; CURRENT_FNVAL=16; stardustvideo=1; rpdid=|(umY))|ukl~0J'ulY~uJm)kJ; UM_distinctid=16ce0e51cf0abc-02da63c2df0b4b-5373e62-1fa400-16ce0e51cf18d8; stardustpgcv=0606; im_notify_type_33717177=0; finger=b3372c5f; CURRENT_QUALITY=112; bp_t_offset_33717177=300203628285382610"
}

CRC_POLYNOMIAL = 0xEDB88320
crc_table = [0 for x in range(256)]


def create_table():
    for i in range(256):
        crc_reg = i
        for _ in range(8):
            if (crc_reg & 1) != 0:
                crc_reg = CRC_POLYNOMIAL ^ (crc_reg >> 1)
            else:
                crc_reg = crc_reg >> 1
        crc_table[i] = crc_reg


def crc32(string):
    crc_start = 0xFFFFFFFF
    for i in range(len(str(string))):
        index = (crc_start ^ ord(str(string)[i])) & 255
        crc_start = (crc_start >> 8) ^ crc_table[index]
    return crc_start


def crc32_last_index(string):
    crc_start = 0xFFFFFFFF
    for i in range(len(str(string))):
        index = (crc_start ^ ord(str(string)[i])) & 255
        crc_start = (crc_start >> 8) ^ crc_table[index]
    return index


def get_crc_index(t):
    for i in range(256):
        if crc_table[i] >> 24 == t:
            return i
    return -1


def deep_check(i, index):
    string = ""
    hashcode = crc32(i)
    tc = hashcode & 0xff ^ index[2]
    if not (57 >= tc >= 48):
        return [0]
    string += str(tc - 48)
    hashcode = crc_table[index[2]] ^ (hashcode >> 8)
    tc = hashcode & 0xff ^ index[1]
    if not (57 >= tc >= 48):
        return [0]
    string += str(tc - 48)
    hashcode = crc_table[index[1]] ^ (hashcode >> 8)
    tc = hashcode & 0xff ^ index[0]
    if not (57 >= tc >= 48):
        return [0]
    string += str(tc - 48)
    return [1, string]


def dec(string):
    index = [0 for x in range(4)]
    i = 0
    ht = int(f"0x{string}", 16) ^ 0xffffffff
    for i in range(3, -1, -1):
        index[3 - i] = get_crc_index(ht >> (i * 8))
        snum = crc_table[index[3 - i]]
        ht ^= snum >> ((3 - i) * 8)
    for i in range(100000000):
        last_index = crc32_last_index(i)
        if last_index == index[3]:
            deepCheckData = deep_check(i, index)
            if deepCheckData[0]:
                break
    if i == 0:
        return -1
    return f"{i}{deepCheckData[1]}"


def get_oid(vid):
    print('开始获取oid')
    _resp = req.get('https://www.bilibili.com/video/' + vid, headers=headers)
    match_rule = r'cid=(.*?)&aid'
    oid = search(match_rule, _resp.text).group().replace('cid=', '').replace('&aid', '')
    return oid


def get_text(oid):
    print('开始爬取内容')
    api_url = 'https://api.bilibili.com/x/v1/dm/list.so?oid=' + oid
    _data = req.get(api_url, headers=headers)
    _data.encoding = 'utf-8'
    return _data
    
    
def Pause():
    system("echo 按任意键继续")
    system("read -n 1")


if __name__ == "__main__":
    try:
        vid = input('输入av或BV号:')
        oid = get_oid(vid)
    except:
        print('oid获取失败')
        print('请检查网络连接、视频号输入是否正确')
        Pause()
        exit(0)
    else:
        print('oid获取成功')

    try:
        resp = get_text(oid)
    except:
        print('内容爬取失败 api可能未生效')
        Pause()
        exit(0)
    else:
        if resp.status_code != 200:
            print('出现问题:原视频失效或服务器故障')
            print('请检查视频是否已经失效')
            Pause()
            exit(0)
        else:
            print('内容爬取成功')

    data = findall('<d p="(.*?)">', resp.text)
    content = findall('">(.*?)</d>', resp.text)

    try:
        print('------------------------------------------')
        create_table()
        for i in range(0, len(data)):
            mid_hash = data[i].split(',')[6]
            print(str(i + 1) + '. 用户uid:' + dec(mid_hash) + ' 弹幕内容:' + content[i])
            if i > 0 and i % 100 == 0:
                Pause()
    except:
        print('------------------------------------------')
        print('查询可能出现问题 不支持高级、代码、GAS弹幕')
    else:
        print('------------------------------------------')
        print('查询完成 不支持高级、代码、GAS弹幕')
    print('~吾爱破解：ArcmentNC')
    Pause()
